package com.dragon.logical.service.auth.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.common.constant.PlatformConstant;
import com.dragon.common.model.ResultCode;
import com.dragon.common.model.exception.CustomException;
import com.dragon.common.util.JwtUtil;
import com.dragon.common.util.RedisUtil;
import com.dragon.logical.service.auth.AdminService;
import com.dragon.logical.service.auth.TasksService;
import com.dragon.logical.service.netty.NettyClientService;
import com.dragon.logical.service.reminder.IDoReminderService;
import com.dragon.repository.entity.*;
import com.dragon.repository.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author sy
 * @since 2023-06-12
 */
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {

    private final static String USER_LOGIN_PREFIX = "TOKEN:";

    private final static String USER_LOGIN_PLATFORM = "CRM_PLATFORM";


    @Autowired
    TasksService scheduleService;

    @Autowired
    AdminMapper mapper;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    AdminDepartmentMapper adminDepartmentMapper;


    @Autowired
    RoleMenuMapper roleMenuMapper;

    @Autowired
    MenuMapper menuMapper;

    @Autowired
    RoleMapper roleMapper;

    @Autowired
    DepartmentMapper departmentMapper;

    @Autowired
    RoleDepartmentMapper roleDepartmentMapper;

    @Autowired
    AdminRoleMapper adminRoleMapper;

    @Autowired
    NettyClientService nettyClientService;

    @Autowired
    IDoReminderService reminderService;

    @Autowired
    AdminPositionMapper adminPositionMapper;

    @Autowired
    ModMapper modMapper;

    @Autowired
    PositionMapper positionMapper;

    @Autowired
    RedisUtil redisUtil;


    @Override
    public Page<Admin> selectPage(String search, Integer departmentId, Integer page, Integer limit) {
        Page<Admin> adminPage = new Page<>(page, limit);
        //获取所有下级部门id
        List<Department> departmentList = departmentMapper.selectDepartmentListByAdminId(departmentId);
        List<Integer> integerList = departmentList.stream().map(Department::getId).collect(Collectors.toList());
        Page<Admin> adminList = mapper.selectPageBySearch(adminPage, search, integerList);
        return adminList;
    }


    @Override
    public List<Admin> selectAdminList(Integer adminId){
        List<Admin> adminList = mapper.selectAdminList(adminId);
        return adminList;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void add(Admin admin) {

        //查询当前用户是否有重复电话号码
        QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Admin::getState, 1).eq(Admin::getAccount,admin.getAccount()).eq(Admin::getDeleted,0);
        Admin admin1 = mapper.selectOne(queryWrapper);

        if(admin1 != null){
            throw new CustomException(ResultCode.ACCOUNT_REPEAT);
        }


        // 手机号码去重
        queryWrapper.clear();
        queryWrapper.lambda().eq(Admin::getState, 1).eq(Admin::getPhone,admin.getPhone()).eq(Admin::getDeleted,0);

        Admin admin2 = mapper.selectOne(queryWrapper);
        if(admin2 != null){
            throw new CustomException(ResultCode.PHONE_REPEAT);
        }

        //加密后的密码
        String encodePassword = passwordEncoder.encode(admin.getPassword());
        admin.setPassword(encodePassword);
        admin.setCreateTime(DateUtil.date());
        //用户表
        mapper.insert(admin);

        //用户角色关联表
        AdminRole adminRole = new AdminRole();
        adminRole.setAdminId(admin.getId());
        adminRole.setRoleId(admin.getRoleId());
        adminRoleMapper.insert(adminRole);
        //用户部门关联表

        AdminDepartment adminDepartment = new AdminDepartment();
        adminDepartment.setAdminId(admin.getId());
        adminDepartment.setDepartmentId(admin.getDepartmentId());
        adminDepartmentMapper.insert(adminDepartment);
        //用户岗位关联表
        Position position = positionMapper.selectById(admin.getPositionId());
        // 直接主管
        if(position.getManagementState() == 1){
            List<AdminPosition> positions = adminPositionMapper.selectByAdminDeleted(position.getId());
            if(positions.size() >0 ){
                throw new CustomException(ResultCode.POSITION_IS_EXIT);
            }
        }
        AdminPosition adminPosition = new AdminPosition();
        adminPosition.setPositionId(admin.getPositionId());
        adminPosition.setAdminId(admin.getId());
        adminPositionMapper.insert(adminPosition);
    }


    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void update(Admin admin) {
        Admin admins = mapper.selectById(admin.getId());
        if (admins == null) {
            throw new CustomException(ResultCode.DATA_NOT_FOUND);
        }
        admin.setUpdateTime(DateUtil.date());
        mapper.updateById(admin);

        /*用户角色关联表*/
        QueryWrapper<AdminRole> adminRoleQueryWrapper = new QueryWrapper<>();
        adminRoleQueryWrapper.lambda().eq(AdminRole::getAdminId, admin.getId());
        AdminRole adminRole = adminRoleMapper.selectOne(adminRoleQueryWrapper);
        if (adminRole == null) {
            //添加
            adminRole = new AdminRole();
            adminRole.setAdminId(admin.getId());
            adminRole.setRoleId(admin.getRoleId());
            adminRoleMapper.insert(adminRole);
        } else {
            //修改
            adminRole.setRoleId(admin.getRoleId());
            adminRole.setUpdateTime(DateUtil.date());
            adminRoleMapper.updateById(adminRole);
        }

        /*角色部门表*/
        QueryWrapper<AdminDepartment> adminDepartmentQueryWrapper = new QueryWrapper<>();
        adminDepartmentQueryWrapper.lambda().eq(AdminDepartment::getAdminId, admin.getId());
        AdminDepartment adminDepartment = adminDepartmentMapper.selectOne(adminDepartmentQueryWrapper);
        if (adminDepartment == null) {
            adminDepartment = new AdminDepartment();
            adminDepartment.setAdminId(admin.getId());
            adminDepartment.setDepartmentId(admin.getDepartmentId());
            adminDepartmentMapper.insert(adminDepartment);
        } else {
            adminDepartment.setDepartmentId(admin.getDepartmentId());
            adminDepartment.setUpdateTime(DateUtil.date());
            adminDepartmentMapper.updateById(adminDepartment);
        }

        //用户岗位关联表
        Position position = positionMapper.selectById(admin.getPositionId());
        if (position != null){
            // 直接主管
            if(position.getManagementState() == 1){
                List<AdminPosition> positions = adminPositionMapper.selectList(
                        new QueryWrapper<AdminPosition>().lambda()
                                .eq(AdminPosition::getPositionId,admin.getPositionId())
                                .ne(AdminPosition::getAdminId,admin.getId())
                );
                if(positions.size() >0 ){
                    throw  new CustomException(ResultCode.POSITION_IS_EXIT);
                }
            }
        }

        //用户岗位表
        QueryWrapper<AdminPosition> adminPositionQueryWrapper = new QueryWrapper<>();
        adminPositionQueryWrapper.lambda().eq(AdminPosition::getAdminId, admin.getId());
        AdminPosition adminPosition = adminPositionMapper.selectOne(adminPositionQueryWrapper);
        if (adminPosition == null) {
            adminPosition = new AdminPosition();
            adminPosition.setAdminId(admin.getId());
            adminPosition.setPositionId(admin.getPositionId());
            adminPositionMapper.insert(adminPosition);
        } else {
            adminPosition.setPositionId(admin.getPositionId());
            adminPosition.setUpdateTime(DateUtil.date());
            adminPositionMapper.updateById(adminPosition);
        }



    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void delete(Integer id) {
        Admin admins = mapper.selectById(id);
        if (admins == null) {
            throw new CustomException(ResultCode.DATA_NOT_FOUND);
        }
        //用户部门表
        QueryWrapper<AdminDepartment> departmentQueryWrapper = new QueryWrapper<>();
        departmentQueryWrapper.lambda().eq(AdminDepartment::getAdminId, id);
        adminDepartmentMapper.delete(departmentQueryWrapper);

        //角色用户表
        QueryWrapper<AdminRole> adminRoleQueryWrapper = new QueryWrapper<>();
        adminRoleQueryWrapper.lambda().eq(AdminRole::getAdminId, id);
        adminRoleMapper.delete(adminRoleQueryWrapper);

        //用户岗位表
        adminPositionMapper.delete(new LambdaQueryWrapper<AdminPosition>().eq(AdminPosition::getAdminId,id));

        admins.setDeleted(1);
        mapper.updateById(admins);
    }


    @Override
    public String login(String account, String phone, String password, Boolean remember,PlatformConstant platformConstant) {
        QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Admin::getState, 1).and(wq -> {
            wq.eq(Admin::getAccount, account).or().eq(Admin::getPhone, account);
        });
        Admin admin = mapper.selectOne(queryWrapper);
        if (admin == null) {
            throw new CustomException(ResultCode.USER_INFO_NOT_FOUND);
        }
        if (!passwordEncoder.matches(password, admin.getPassword())) {
            throw new CustomException(ResultCode.USER_INFO_NOT_PASSWORD_ERROR);
        }

        AdminToken adminToken = new AdminToken();
        adminToken.setId(admin.getId());
        adminToken.setUsername(admin.getUsername());
        adminToken.setIsAdmin(admin.getAccountType());

        LocalDateTime issueAt = LocalDateTime.now();
        LocalDateTime expireAt = issueAt.plusSeconds(remember ? TimeUnit.DAYS.toSeconds(JwtUtil.DAY) : TimeUnit.MINUTES.toSeconds(30));
        int expireSeconds = (int) Duration.between(issueAt, expireAt).getSeconds();
        adminToken.setExpiresAt(expireAt);
        adminToken.setRemember(remember);
        adminToken.setPlatformConstant(platformConstant);
        String token = JwtUtil.generateToken(JSONUtil.toJsonStr(adminToken));
        //生成md5字符串
        adminToken.setMd5TokenStr(DigestUtil.md5Hex(token));
        String key = generateKey(admin.getId(),platformConstant);
        redisUtil.deleteBySuffix(key);
        // 添加到redis中去
        redisUtil.set(key, adminToken, expireSeconds);
        return token;
    }


    @Override
    public void logout(Integer id, PlatformConstant platformConstant){
        redisUtil.deleteBySuffix(generateKey(id,platformConstant));
    }


    @Override
    public String generateKey(Integer id,PlatformConstant platformConstant) {
        String key = USER_LOGIN_PREFIX.concat(String.valueOf(id)).concat(USER_LOGIN_PLATFORM).concat(platformConstant.toString());
        return key;
    }


    @Override
    public Admin getAdminInfo(Integer id) {
        // 获取用户基本信息
        Admin admin = mapper.selectById(id);
        if (admin == null) {
            throw new CustomException(ResultCode.USER_INFO_NOT_FOUND);
        }

        // 管理员
        if(admin.getAccountType() == 1){
            admin.setDepartmentName("总公司");
            admin.setRoleName("超级管理员");
            admin.setPositionName("超级管理员");
            admin.setDepartmentId(0);
        }

        //获取部门
        Department department = departmentMapper.selectDepartmentInfoByAdminId(id);
        if (department != null) {
            admin.setDepartmentId(department.getId());
            admin.setDepartmentName(department.getName());
        }
        Role role = roleMapper.selectRoleInfoByAdminId(id);
        if (role != null) {
            admin.setRoleName(role.getRoleName());
        }
        Position position = adminPositionMapper.selectPositionInfoByAdminId(id);
        if (position != null) {
            admin.setPositionName(position.getName());
        }

        // 获取角色的对应的菜单权限
        List<Menu> roleIdList = roleMenuMapper.selectMenuSetById(id);
        if (roleIdList == null && admin.getAccountType()==2) {
            return admin;
        }
        List<Integer> menuIds = roleIdList.stream().map(Menu::getId).collect(Collectors.toList());
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Menu::getEnabled, 1).in(admin.getAccountType() == 2, Menu::getId, menuIds);
        queryWrapper.lambda().orderByAsc(Menu::getSort);
        List<Menu> menuList = menuMapper.selectList(queryWrapper);
        //菜单集合
        List<Menu> menus = menuList.stream().filter(menu -> menu.getType() == 0).collect(Collectors.toList());
        admin.setMenuList(menus);

        // 获取按钮集合
        List<String> bonttonList = menuList.stream().filter(menu -> menu.getType() == 3).map(Menu::getPath).collect(Collectors.toList());
        admin.setBonttonList(bonttonList);

        List<Mod> mods = new ArrayList<>();

        if(admin.getAccountType()==2){
            //获取控制台配置项
            mods = modMapper.selectListByRoleId(role.getId());
        } else {

            mods = modMapper.selectList(null);
        }

        if(mods!=null&&mods.size()!=0){
            admin.setModList(mods);
        }

        return admin;

    }

    @Override
    public Admin getAdminInfoById(Integer id) {
        Admin admin = mapper.selectById(id);
        return admin;
    }

    @Override
    public Admin getAdminInfoByAccount(String account) {
        QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Admin::getAccount, account);
        Admin admin = mapper.selectOne(queryWrapper);
        return admin;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void deleteAdminList(List<Integer> adminIds) {
        QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(Admin::getId, adminIds);
        List<Admin> admins = mapper.selectList(queryWrapper);
        if (adminIds.size() != admins.size()) {
            throw new CustomException(ResultCode.DATA_NOT_FOUND);
        }

        //用户部门表
        QueryWrapper<AdminDepartment> departmentQueryWrapper = new QueryWrapper<>();
        departmentQueryWrapper.lambda().in(AdminDepartment::getAdminId, adminIds);
        adminDepartmentMapper.delete(departmentQueryWrapper);

        //角色用户表
        QueryWrapper<AdminRole> adminRoleQueryWrapper = new QueryWrapper<>();
        adminRoleQueryWrapper.lambda().in(AdminRole::getAdminId, adminIds);
        adminRoleMapper.delete(adminRoleQueryWrapper);

        //用户岗位表
        adminPositionMapper.delete(new LambdaQueryWrapper<AdminPosition>().in(AdminPosition::getAdminId,adminIds));

        Admin admin = new Admin();
        admin.setDeleted(1);
        mapper.update(admin,queryWrapper);
    }

    @Override
    public Boolean changeState(Integer adminId, Integer state) {
        QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Admin::getId, adminId);
        Admin admin = mapper.selectOne(queryWrapper);
        if (admin == null) {
            throw new CustomException(ResultCode.DATA_NOT_FOUND);
        }
        if (state > 2 || state <= 0) {
            throw new CustomException(ResultCode.PARAM_IS_INVALID);
        }
        admin.setState(state);
        mapper.update(admin, queryWrapper);
        return true;
    }

    @Override
    public void changePassword(Integer adminId, String oldPassword, String password, String confirmPassword) {

        Admin admin = mapper.selectOne(new QueryWrapper<Admin>().lambda().eq(Admin::getId, adminId));
        // 判断原密码与正确密码是否相同
        if (!passwordEncoder.matches(oldPassword, admin.getPassword())) {
            throw new CustomException(ResultCode.USER_TWO_PASSWORD_NOT_SOME);
        }

        if (!password.equals(confirmPassword)) {
            throw new CustomException(ResultCode.USER_TWO_PASSWORD_NOT_SOME);
        }
        String encode = passwordEncoder.encode(password);
        admin.setPassword(encode);
        mapper.updateById(admin);
    }

    @Override
    public void resetPassword(List<Integer> ids) {
        QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(Admin::getId, ids);
        List<Admin> admins = mapper.selectList(queryWrapper);
        if (admins.size() != ids.size()) {
            throw new CustomException(ResultCode.DATA_NOT_FOUND);
        }
        for (Admin adminSub : admins) {
            String encode = passwordEncoder.encode("123456");
            adminSub.setPassword(encode);
            mapper.updateById(adminSub);
        }
    }

    @Override
    public Integer selectAdminIdByAccountOrPhone(Object[] objects) {
        for (Object o : objects) {
            if (StrUtil.isBlank(o.toString())) {
                break;
            }
            String param = o.toString();
            QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(Admin::getDeleted,0).eq(Admin::getState, 1).and(wq -> {
                wq.eq(Admin::getAccount, param).or().eq(Admin::getPhone, param);
            });
            Admin admin = mapper.selectOne(queryWrapper);
            if (admin == null){
                throw new CustomException(ResultCode.ACCOUNT_IS_NOT_REPEAT);
            }
            return admin.getId();
        }
        return 0;
    }

    @Override
    public Admin getAdminMod(Integer id) {
        // 获取用户基本信息
        Admin admin = mapper.selectById(id);
        if (admin == null) {
            throw new CustomException(ResultCode.USER_INFO_NOT_FOUND);
        }

        // 管理员
        if(admin.getAccountType() == 1){
            admin.setDepartmentName("总公司");
            admin.setRoleName("超级管理员");
            admin.setPositionName("超级管理员");
            admin.setDepartmentId(0);
        }

        //获取部门
        Department department = departmentMapper.selectDepartmentInfoByAdminId(id);
        if (department != null) {
            admin.setDepartmentId(department.getId());
            admin.setDepartmentName(department.getName());
        }
        Role role = roleMapper.selectRoleInfoByAdminId(id);
        if (role != null) {
            admin.setRoleName(role.getRoleName());
        }
        Position position = adminPositionMapper.selectPositionInfoByAdminId(id);
        if (position != null) {
            admin.setPositionName(position.getName());
        }

        List<Mod> mods = new ArrayList<>();

        if(admin.getAccountType()==2){
            //获取控制台配置项
            mods = modMapper.selectListByRoleId(role.getId());
        } else {

            mods = modMapper.selectList(null);
        }

        if(mods!=null&&mods.size()!=0){
            admin.setModList(mods);
        }

        return admin;

    }
}
